package com.chance.cc.crawler.development.controller;

import com.chance.cc.crawler.core.CrawlerController;
import com.chance.cc.crawler.core.CrawlerJob;
import com.chance.cc.crawler.core.CrawlerJobBuilder;
import com.chance.cc.crawler.core.downloader.proxy.MultiConfigProxyProvider;
import com.chance.cc.crawler.core.queue.crawler.CrawlerQueueConfig;
import com.chance.cc.crawler.core.record.CrawlerRequestRecord;
import com.chance.cc.crawler.core.script.clazz.ClazzScriptLoader;
import com.chance.cc.crawler.core.script.crawler.CrawlerGroovyInstance;
import org.apache.commons.lang3.StringUtils;

/**
 * created by CC on 2020/11/5
 * mail 279020185@qq.com
 */
public class DevCrawlerController {

   private CrawlerController crawlerController ;

   private CrawlerJob crawlerJob;

   public void start(){
      crawlerController.registerCrawler(this.crawlerJob);
      this.crawlerController.start();
   }

   private DevCrawlerController(CrawlerJob crawlerJob,String clazzLoaderScope){
      this.crawlerJob = crawlerJob;

      crawlerController = new CrawlerController();

      //init dev script loader
      ClazzScriptLoader loader = null;
      if (StringUtils.isNotBlank(clazzLoaderScope)){
         loader = new ClazzScriptLoader(new CrawlerGroovyInstance(),null,null,clazzLoaderScope);
      }else{
         loader = new ClazzScriptLoader(new CrawlerGroovyInstance());
      }
      crawlerController.registryScriptLoader(loader);
      //keep running
      crawlerController.setShutdownWhenCrawlerEmpty(true);
      //set proxy provider
      crawlerController.setProxyProvider(new MultiConfigProxyProvider());
   }

   private DevCrawlerController(CrawlerJob crawlerJob){
      this(crawlerJob,null);
   }


   public CrawlerJob getCrawlerJob() {
      return crawlerJob;
   }

   public void setCrawlerJob(CrawlerJob crawlerJob) {
      this.crawlerJob = crawlerJob;
   }

   public static DevCrawlerControllerBuilder builder(){
      return new DevCrawlerControllerBuilder();
   }

   public static CrawlerQueueConfig devRequestQueue(String domain){
      CrawlerQueueConfig crawlerQueueConfig = new CrawlerQueueConfig(
              domain, CrawlerQueueConfig.Content.request, CrawlerQueueConfig.Storage.memory, CrawlerQueueConfig.Structure.list
      );

      return crawlerQueueConfig;
   }

   public static class DevCrawlerControllerBuilder{

      private CrawlerJobBuilder crawlerJobBuilder;

      public DevCrawlerControllerBuilder(){
         crawlerJobBuilder = CrawlerJob.builder();
      }

      public DevCrawlerControllerBuilder crawlerThreadNum(int num){
         this.crawlerJobBuilder.crawlerJobThreadNumber(num);
         return this;
      }

      public DevCrawlerControllerBuilder triggerInfo(String domain,String triggerKey,long triggerTime ,String triggerJobKey){
         this.crawlerJobBuilder.triggerInfo(domain,triggerKey,triggerTime,triggerJobKey);
         return this;
      }

      public DevCrawlerControllerBuilder crawlerRequestQueue(CrawlerQueueConfig requestQueueConfig){
         this.crawlerJobBuilder.crawlerRequestQueue(requestQueueConfig);
         return this;
      }

      public DevCrawlerControllerBuilder consoleResultPipeline(){
         return consoleResultPipeline(null);
      }

      public DevCrawlerControllerBuilder consoleResultPipeline(String pipelineKey){
         this.crawlerJobBuilder.consoleResultPipeline(pipelineKey);
         return this;
      }

      public DevCrawlerControllerBuilder fileResultPipeline(String filePath,boolean append){
         return fileResultPipeline(null,filePath,append);
      }

      public DevCrawlerControllerBuilder fileResultPipeline(String pipelineKey,String filePath,boolean append){
         this.crawlerJobBuilder.fileResultPipeline(pipelineKey,filePath,append);
         return this;
      }

      public DevCrawlerControllerBuilder queueResultPipeline(CrawlerQueueConfig queueConfig){
         return queueResultPipeline(null,queueConfig);
      }

      public DevCrawlerControllerBuilder queueResultPipeline(String pipelineKey,CrawlerQueueConfig queueConfig){
         this.crawlerJobBuilder.queueResultPipeline(pipelineKey,queueConfig);
         return this;
      }

      public DevCrawlerControllerBuilder requestRecord(CrawlerRequestRecord requestRecord){
         this.crawlerJobBuilder.requestRecord(requestRecord);
         return this;
      }

      public DevCrawlerControllerBuilder supportRecord(CrawlerRequestRecord supportRecord){
         this.crawlerJobBuilder.supportRecord(supportRecord);
         return this;
      }

      public DevCrawlerController build(){
         return new DevCrawlerController(this.crawlerJobBuilder.build());
      }

      public DevCrawlerController build(String clazzLoaderScope){
         return new DevCrawlerController(this.crawlerJobBuilder.build(),clazzLoaderScope);
      }
   }
}
